package com.dgut.controller;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.dgut.pojo.Area;
import com.dgut.pojo.Record;
import com.dgut.pojo.User;
import com.dgut.pojo.UserForLogin;
import com.dgut.service.AreaService;
import com.dgut.service.RecordService;
import com.dgut.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@CrossOrigin
@Api("DailyController")
@RestController
@RequestMapping("daily")
public class DailyController {

    @Autowired
    private UserService userService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private AreaService areaService;

    /**
     * 用户登录
     * @param userForLogin
     * @return
     */
    @ApiOperation(value = "登录接口",notes = "")
    @PostMapping("/login")
    public Object login(@ApiParam(value = "用户",required = true) @RequestBody UserForLogin userForLogin){
        HashMap map = new HashMap();
        /**
         * 若提交为空则登录失败
         */
        if(userForLogin.getId()==0||userForLogin.getPassword()==""||userForLogin.getPassword()==null){
            map.put("loginResult",false);
            return map;
        }
        User u = null;
        try {
            u = userService.findUserById(userForLogin.getId());
        }catch (IllegalArgumentException e){
            map.put("loginResult",false);
        }
        if(u!=null&&u.getPassword().equals(userForLogin.getPassword())){
            StpUtil.setLoginId(u.getId());
            /**
             * 用户角色获取
             */
            if(StpUtil.hasRole("manage-admin")){
                map.put("role","manage-admin");
            }else if(StpUtil.hasRole("assist-admin")){
                map.put("role","assist-admin");
            }
            /**
             * 查询今日打卡情况
             */
            try{
                /**
                 * 结果null就抛出异常
                 */
                recordService.findTodayRecordById(u.getId());
                map.put("recordFlag",true);
            }catch (IllegalArgumentException e){
                map.put("recordFlag",false);
            }
            map.put("loginResult",true);
            List<Area> highRiskAreas = areaService.findRiskArea(2);
            List<Area> midRiskAreas = areaService.findRiskArea(1);
            Record r = recordService.findNewestRecordById(u.getId());
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            map.put(tokenInfo.getTokenName(),tokenInfo.getTokenValue());
            map.put("user",u);
            map.put("newestRecord",r);
            map.put("highRiskAreas",highRiskAreas);
            map.put("midRiskAreas",midRiskAreas);
        }else{
            map.put("loginResult",false);
        }
        return map;
    }

    /**
     * 注销接口
     */
    @ApiOperation(value = "注销接口")
    @RequestMapping("/logout")
    public void logout(){
        StpUtil.logout();
    }

    /**
     * 用户打卡
     * @param record
     * @return
     */
    @ApiOperation(value = "打卡接口")
    @PostMapping("/record")
    private Object record(@ApiParam(value = "打卡记录",required = true) @RequestBody Record record){

        HashMap map = new HashMap();
        if(StpUtil.isLogin()){
            Long id = Long.parseLong((String)StpUtil.getLoginId());
            try{
                recordService.findTodayRecordById(id);
                map.put("Error","请勿重复提交");
                map.put("recordResult",false);
            }catch (IllegalArgumentException e){
                /**
                 * cacheable方法返回结果null，抛出异常，接收
                 */
                if(record.getTemperature()<34||record.getTemperature()>45){
                    map.put("Error","体温数据异常");
                    map.put("recordResult",false);
                }else{
                    record.setId(id);
                    record.setTime(new Date());
                    recordService.savaRecord(record);
                    /**
                     * 更新累计打卡天数
                     */
                    User user = userService.findUserById(id);
                    if(recordService.findLastDayRecordById(id)!=null){
                        user.setDays(user.getDays()+1);
                    }else {
                        user.setDays(1);
                    }
                    userService.saveUser(user);
                    map.put("recordResult",true);
                }
            }
        }else{
            map.put("Error","请先登录");
            map.put("recordResult",false);
        }
        return map;
    }

    /**
     * 全局异常拦截（拦截项目中的NotLoginException异常）
     * @param nle
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @ExceptionHandler(NotLoginException.class)
    public Object handlerNotLoginException(NotLoginException nle, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        /**
         * 打印堆栈，以供调试
         */
        HashMap map = new HashMap();
        nle.printStackTrace();

        // 判断场景值，定制化异常信息
        String message = "";
        if(nle.getType().equals(NotLoginException.NOT_TOKEN)) {
            message = "未提供token";
        }
        else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) {
            message = "token无效";
        }
        else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
            message = "token已过期";
        }
        else if(nle.getType().equals(NotLoginException.BE_REPLACED)) {
            message = "token已被顶下线";
        }
        else if(nle.getType().equals(NotLoginException.KICK_OUT)) {
            message = "token已被踢下线";
        }
        else {
            message = "当前会话未登录";
        }
        map.put("Error",message);
        return map;
    }
}
